package dao;

/**
 * Responsavel por realizar transações com o BD
 *
 */
import classes.Entrada;
import classes.Fornecedor;
import classes.ItensProduto;
import classes.Produto;
import conexao.GerenciadorConexao;
import erro.ConexaoException;
import erro.ConsultaException;
import erro.DaoException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

public class DaoEntrada implements IDaoEntrada {

    private GerenciadorConexao g;

    public DaoEntrada() {
        g = GerenciadorConexao.getInstancia();
    }

    /**
     * Insere um novo registro no BD
     * @param ent
     * @throws ConexaoException
     * @throws DaoException
     */
    @Override
    public void inserir(Entrada ent, ItensProduto it, Produto prod) throws DaoException, ConexaoException {
        String sql = "INSERT INTO entrada (dataentrada, codproduto, codfornecedor, numlote, quantproduto,"
                + " obsentrada) VALUES (?,?,?,?,?,?)";

        String sqlIt = "INSERT INTO itensproduto (codproduto, numlote, datavalidade, quantitens) VALUES (?,?,?,?)";

        String sqlProd = "UPDATE produto set estproduto="
                + "(select SUM(quantitens) from itensproduto WHERE codproduto=?) where codproduto=?";

        try {
            PreparedStatement pstm = g.connect().prepareStatement(sql);
            PreparedStatement pstmIt = g.connect().prepareStatement(sqlIt);
            PreparedStatement pstmProd = g.connect().prepareStatement(sqlProd);
            pstm.setString(1, ent.getDataEntrada());
            pstm.setInt(2, ent.getCodProduto().getCodProduto());
            pstm.setInt(3, ent.getCodFornecedor().getCodFornecedor());
            pstm.setString(4, ent.getNumLote());
            pstm.setInt(5, ent.getQuantprod());
            pstm.setString(6, ent.getObsEntrada());
            pstm.executeUpdate();

            pstmIt.setInt(1, it.getCodProduto().getCodProduto());
            pstmIt.setString(2, it.getNumLote());
            pstmIt.setString(3, it.getDataValidade());
            pstmIt.setInt(4, it.getQuantItens());
            pstmIt.executeUpdate();

            pstmProd.setInt(1, prod.getCodProduto());
            pstmProd.setInt(2, prod.getCodProduto());
            pstmProd.executeUpdate();

        } catch (SQLException ex) {
            throw new DaoException();
        } finally {
            g.disconnect();
        }
    }

    /**
     * Altera um registro no BD
     * @param ent
     * @throws ConexaoException
     * @throws DaoException 
     */
    @Override
    public void alterar(Entrada ent, ItensProduto it) throws ConexaoException, DaoException {
        String sql = "UPDATE entrada SET dataentrada=?, codproduto=?, codfornecedor=?, numlote=?,quantproduto=?"
                + " obsentrada=?";
        String sqlIt = "UPDATE itensproduto SET codproduto=?, numlote=?, datavalidade=?, quantitens=?";

        try {
            PreparedStatement pstm = (PreparedStatement) g.connect().prepareStatement(sql);
            PreparedStatement pstmIt = (PreparedStatement) g.connect().prepareStatement(sqlIt);
            pstm.setString(1, ent.getDataEntrada());
            pstm.setInt(2, ent.getCodProduto().getCodProduto());
            pstm.setInt(3, ent.getCodFornecedor().getCodFornecedor());
            pstm.setString(4, ent.getNumLote());
            pstm.setInt(5, ent.getQuantprod());
            pstm.setString(6, ent.getObsEntrada());
            pstm.executeUpdate();

            pstmIt.setInt(1, it.getCodProduto().getCodProduto());
            pstmIt.setString(2, it.getNumLote());
            pstmIt.setString(3, it.getDataValidade());
            pstmIt.setInt(4, it.getQuantItens());
            pstmIt.executeUpdate();

        } catch (SQLException ex) {
            throw new DaoException();
        } finally {
            g.disconnect();
        }
    }

    /**
     * Exclui um registro no BD
     * @param ent
     * @throws ConexaoException
     * @throws DaoException 
     */
    @Override
    public void deletar(Entrada ent, Produto prod) throws ConexaoException, DaoException {

        String sql = "DELETE FROM entrada where numlote=?";
        
        String sqlProd = "UPDATE produto set estproduto="
                + "(select SUM(quantitens) from itensproduto WHERE codproduto=?) where codproduto=?";
        
        try {
            PreparedStatement pstm = (PreparedStatement) g.connect().prepareStatement(sql);
            pstm.setString(1, ent.getNumLote());
            pstm.executeUpdate();
            
            PreparedStatement pstmProd = g.connect().prepareStatement(sqlProd);
            pstmProd.setInt(1, prod.getCodProduto());
            pstmProd.setInt(2, prod.getCodProduto());
            pstmProd.executeUpdate();
            
        } catch (SQLException ex) {
            throw new DaoException();
        } finally {
            g.disconnect();
        }
    }

    /**
     * Faz uma pesquisa no BD
     * @param ent
     * @return
     * @throws ConexaoException
     * @throws ConsultaException 
     */
    @Override
    public ItensProduto pesquisarIt(ItensProduto it) throws ConexaoException, DaoException {
        String sql = "SELECT * FROM itensproduto where codproduto=?";
        try {
            Produto prod = new Produto();
            Entrada ent = new Entrada();
            PreparedStatement pstm = g.connect().prepareStatement(sql);
            pstm.setInt(1, it.getCodProduto().getCodProduto());
            ResultSet rs = pstm.executeQuery();
            if (rs.next()) {
                it.setCodProduto(prod);
                it.setNumLote(rs.getString("numlote"));
                it.setQuantItens(rs.getInt("quantitens"));
            }
        } catch (SQLException ex) {
            throw new DaoException();
        } finally {
            g.disconnect();
        }
        return it;
    }
    
    @Override
    public Entrada pesquisar(Entrada ent) throws ConexaoException, DaoException {
       String sql = "select ent.codentrada, ent.dataentrada, prod.codproduto, prod.descproduto, fornec.codfornecedor, "
                + "fornec.cnpjfornecedor, ent.numlote,"
                + " ent.quantproduto, ent.obsentrada from entrada ent "
                + "inner join produto prod on ent.codproduto=prod.codproduto "
                + "inner join fornecedor fornec on ent.codfornecedor=fornec.codfornecedor"
                + " where codentrada=?";
        try {
            Produto prod = new Produto();
            Fornecedor fornec = new Fornecedor(); 
            PreparedStatement pstm = g.connect().prepareStatement(sql);
            pstm.setInt(1, ent.getCodEntrada());
            ResultSet rs = pstm.executeQuery();
            if (rs.next()) {
                ent = new Entrada();
                prod = new Produto();
                fornec = new Fornecedor();
                ent.setCodEntrada(rs.getInt("codentrada"));
                ent.setDataEntrada(rs.getString("dataentrada"));
                prod.setCodProduto(rs.getInt("codproduto"));
                prod.setDescProduto(rs.getString("descproduto"));
                ent.setCodProduto(prod);
                fornec.setCodFornecedor(rs.getInt("codfornecedor"));
                fornec.setCnpjFornecedor(rs.getString("cnpjfornecedor"));
                ent.setCodFornecedor(fornec);
                ent.setNumLote(rs.getString("numlote"));
                ent.setQuantprod(rs.getInt("quantprod"));
                ent.setObsEntrada(rs.getString("obsentrada"));
            }
        } catch (SQLException ex) {
            throw new DaoException();
        } finally {
            g.disconnect();
        }
        return ent;
    }
    @Override
      public List<Entrada> pesquisarEnt(Entrada ent) throws ConexaoException, ConsultaException {
        List<Entrada> lista = new ArrayList<Entrada>();
        Produto prod;
        Fornecedor fornec;
        String sql = "select ent.codentrada, ent.dataentrada, prod.codproduto, prod.descproduto, fornec.codfornecedor, "
                + "fornec.nomefornecedor, ent.numlote,"
                + " ent.quantproduto, ent.obsentrada from entrada ent "
                + "inner join produto prod on ent.codproduto=prod.codproduto "
                + "inner join fornecedor fornec on ent.codfornecedor=fornec.codfornecedor"
                + " where dataentrada=?";
        try {
            PreparedStatement pstm = g.connect().prepareStatement(sql);
            pstm.setString(1, ent.getDataEntrada());
            ResultSet rs = pstm.executeQuery();
            while (rs.next()) {
                ent = new Entrada();
                prod = new Produto();
                fornec = new Fornecedor();
                ent.setCodEntrada(rs.getInt("codentrada"));
                ent.setDataEntrada(rs.getString("dataentrada"));
                prod.setCodProduto(rs.getInt("codproduto"));
                prod.setDescProduto(rs.getString("descproduto"));
                ent.setCodProduto(prod);
                fornec.setCodFornecedor(rs.getInt("codfornecedor"));
                fornec.setNomeFornecedor(rs.getString("nomefornecedor"));
                ent.setCodFornecedor(fornec);
                ent.setNumLote(rs.getString("numlote"));
                ent.setQuantprod(rs.getInt("quantproduto"));
                ent.setObsEntrada(rs.getString("obsentrada"));
                lista.add(ent);
            }
        } catch (SQLException ex) {
            throw new ConsultaException();
        } finally {
            g.disconnect();
        }
        return lista;
      }
      
    @Override
     public List<Entrada> listarEnt() throws ConexaoException, ConsultaException {
        List<Entrada> lista = new ArrayList<Entrada>();
        Entrada ent;
        Produto prod;
        Fornecedor fornec;
        String sql = "select ent.codentrada, ent.dataentrada, prod.codproduto, prod.descproduto, fornec.codfornecedor, "
                + "fornec.nomefornecedor, ent.numlote,"
                + " ent.quantproduto, ent.obsentrada from entrada ent "
                + "inner join produto prod on ent.codproduto=prod.codproduto "
                + "inner join fornecedor fornec on ent.codfornecedor=fornec.codfornecedor"
                + " order by dataentrada";
        try {
            Statement stm = (Statement) g.connect().createStatement();
            ResultSet rs = stm.executeQuery(sql);
            while (rs.next()) {
                ent = new Entrada();
                prod = new Produto();
                fornec = new Fornecedor();
                ent.setCodEntrada(rs.getInt("codentrada"));
                ent.setDataEntrada(rs.getString("dataentrada"));
                prod.setCodProduto(rs.getInt("codproduto"));
                prod.setDescProduto(rs.getString("descproduto"));
                ent.setCodProduto(prod);
                fornec.setCodFornecedor(rs.getInt("codfornecedor"));
                fornec.setNomeFornecedor(rs.getString("nomefornecedor"));
                ent.setCodFornecedor(fornec);
                ent.setNumLote(rs.getString("numlote"));
                ent.setQuantprod(rs.getInt("quantproduto"));
                ent.setObsEntrada(rs.getString("obsentrada"));
                lista.add(ent);
            }
        } catch (SQLException ex) {
            throw new ConsultaException();
        } finally {
            g.disconnect();
        }
        return lista;
    }
    
    @Override
     public List<ItensProduto> listar(ItensProduto ip) throws ConexaoException, ConsultaException {
        List<ItensProduto> lista = new ArrayList<ItensProduto>();
        String sql = "select *from itensproduto where codproduto=? order by coditens";
        try {
             PreparedStatement pstm = g.connect().prepareStatement(sql);
            pstm.setInt(1, ip.getCodProduto().getCodProduto());
            ResultSet rs = pstm.executeQuery();
          // Statement stm = (Statement) g.connect().createStatement();
           // ResultSet rs = stm.executeQuery(sql);
            while (rs.next()) {
                ip = new ItensProduto();
                
                ip.setNumLote(rs.getString("numlote"));
                ip.setDataValidade(rs.getString("datavalidade"));
                ip.setQuantItens(rs.getInt("quantitens"));
                lista.add(ip);
            }
        } catch (SQLException ex) {
            throw new ConsultaException();
        } finally {
            g.disconnect();
        }
        return lista;
    }
}
